# -*- coding: UTF-8 -*-

class AudioPlayer51:
  
  def __init__(self):
    from CueParser import CueParser
    from os.path import abspath
    from os.path import dirname
    from os.path import expanduser
    from os.path import exists as pathexists
    from os.path import join as joinpath
    from os.path import splitext as splitpath
    from os import name as osname
    from sys import argv as argv
    from ImageTk import PhotoImage
    from PIL import Image
    import ConfigParser
    from appVersion import versionInfo
    import Tkinter as tk
    import audiere
    from math import exp
    self.tkActive = tk.ACTIVE
    self.tkDisabled = tk.DISABLED
    ver = versionInfo()
    self.name = ver.name
    self.ver = ver.version
    self.audiolib = 'Audiere v' + audiere.get_version()
    
    # Initialise the Window
    self.root = tk.Tk()
    self.root.title(self.name + " v" + str(self.ver))
    self.device = audiere.open_device()
    self.skipbuffsamp = 0
    self.currenttrack = 1
    self.gotfile = 0
    self.skipbuffms = 1000
    self.cue = CueParser()
    self.path = abspath(dirname(argv[0]))
    self.root.winfo_toplevel().resizable(tk.NO, tk.NO)
    if osname == 'nt':
      self.root.winfo_toplevel().wm_iconbitmap(joinpath(self.path, 'AudioPlayer51.ico'))
    
    configfile = joinpath(self.path, "AP51Config.ini")
    loadfile = ''
    
    # Command Line Switches
    if len(argv) > 1:
      for i in range(1, len(argv)):
        arg = argv[i].strip("\"").split('=')
        if len(arg) == 1:
          if (arg[0] == '--help') | (arg[0] == '-h'):
            print self.name + " v" + self.ver + "  " + ver.copyright + "\n\nCommand line switches:\n"
            print "--help - prints this help message"
            print "--version - prints version information"
            print "--soundfile=/path/to/file - specify a soundfile to play. Playback begins immediately"
            print "--configfile=/path/to/file - specify a configuration file to use\n"
            return
          elif (arg[0] == '--version') | (arg[0] == '-v'):
            print self.name + " v" + self.ver + "  " + ver.copyright + "\n"
            return
          else: # Assume a soundfile
            thisfile = arg[0].strip("\"\'")
            thisext = splitpath(thisfile)[1]
            if (thisext != '.flac') and (thisext != '.cue'):
              print ("Invalid file type (must be '.flac' or '.cue'):  %s" % thisfile)
              return
            elif not pathexists(thisfile):
              print ("Unrecognized switch:  %s" % thisfile)
              return
            else:
              loadfile = thisfile
        elif len(arg) == 2:
          thisfile = arg[1].strip("\"\'")
          thisext = splitpath(thisfile)[1]
          if (arg[0] == '--soundfile') | (arg[0] == '-s'):
            if (thisext != '.flac') and (thisext != '.cue'):
              print ("Invalid file type (must be '.flac' or '.cue'):  %s" % thisfile)
              return
            elif not pathexists(arg[1]):
              print ("File not found:  %s" % thisfile)
              return
            else:
              loadfile = arg[1]
          elif (arg[0] == '--configfile') | (arg[0] == '-c'):
            if (thisext != '.ini'):
              print ("Invalid config file (must be '.ini'):  %s" % thisfile)
              return
            elif not pathexists(arg[1]):
              print ("Config file not found:  %s" % thisfile)
              return
            else:
              configfile = arg[1]

    # Settings:
    config = ConfigParser.ConfigParser()
    config.read(configfile)
    if config.has_option("behavior", "cuetag"):
      self.flactagforcue = config.get("behavior", "cuetag")
    else: self.flactagforcue = "cue"
    if config.has_option("behavior", "seek_ms"):
      self.seekms = config.getint("behavior", "seek_ms")
    else: self.seekms = 5000
    if config.has_option("behavior", "initialdir"):
      self.initialDir = config.get("behavior", "initialdir")
    else: self.initialDir = 'HOME'
    if self.initialDir == 'HOME':
      self.initialDir = expanduser("~")
    if config.has_option("behavior", "volumestep"):
      self.volStep = exp(config.getint("behavior", "volumestep")/8.6860)
    else: self.volStep = exp(1/8.6860)
    if config.has_option("display", "refresh_ms"):
      self.refreshms = config.getint("display", "refresh_ms")
    else: self.refreshms = 800
    if config.has_option("display", "showcover"):
      self.showCover = config.getboolean("display", "showcover")
    else: self.showCover = True
    if config.has_option("display", "showblankcover"):
      self.showBlankCover = config.getboolean("display", "showblankcover")
    else: self.showBlankCover = True
    if config.has_option("display", "covermaxsize"):
      self.coverMaxSize = eval(config.get("display", "covermaxsize"))
    else: self.coverMaxSize = 240, 240
    if config.has_option("display", "fontsize"):
      self.fontsize = config.getint("display", "fontsize")
    if config.has_option("display", "fontsize"):
      self.showSlider = config.getboolean("display", "showslider")
    else: self.showSlider = True
    if config.has_option("metadata", "title"):
      self.titleText = config.get("metadata", "title")
    else: self.titleText = self.name + " v" + self.ver
    if config.has_option("behavior", "checkver"):
      checkver = config.getboolean("behavior", "checkver")
    else: checkver = False
    if checkver:
      ver.checkVer()
    
    # Keybindings:
    self.key_back = config.getint("keybindings", "back")
    self.key_next = config.getint("keybindings", "next")
    self.key_play = config.getint("keybindings", "play")
    self.key_stop = config.getint("keybindings", "stop")
    self.key_file = config.getint("keybindings", "file")
    self.key_ffwd = config.getint("keybindings", "ffwd")
    self.key_rwnd = config.getint("keybindings", "rwnd")
    self.key_about = config.getint("keybindings", "about")
    self.key_v_up = config.getint("keybindings", "v_up")
    self.key_v_dn = config.getint("keybindings", "v_dn")

    # Controls:
    controlframe = tk.Frame(self.root,padx=0)
    controlframe.grid(row=0)
    imback = PhotoImage(file=joinpath(self.path, 'images', 'player_back.png'))
    imrwnd = PhotoImage(file=joinpath(self.path, 'images', 'player_rwnd.png'))
    self.implay = PhotoImage(file=joinpath(self.path, 'images', 'player_play.png'))
    self.impause = PhotoImage(file=joinpath(self.path, 'images', 'player_pause.png'))
    imstop = PhotoImage(file=joinpath(self.path, 'images', 'player_stop.png'))
    imffwd = PhotoImage(file=joinpath(self.path, 'images', 'player_ffwd.png'))
    imnext = PhotoImage(file=joinpath(self.path, 'images', 'player_next.png'))
    imfile = PhotoImage(file=joinpath(self.path, 'images', 'player_file.png'))
    imabout = PhotoImage(file=joinpath(self.path, 'images', 'player_about.png'))
    self.backbutton = tk.Button(controlframe,image=imback,relief=tk.FLAT, borderwidth=0, command=self.cmd_back, state=self.tkDisabled)
    self.rwndbutton = tk.Button(controlframe,image=imrwnd,relief=tk.FLAT, borderwidth=0, command=self.cmd_rwnd, state=self.tkDisabled)
    self.playbutton = tk.Button(controlframe,image=self.implay,relief=tk.FLAT, borderwidth=0, command=self.cmd_play, state=self.tkDisabled)
    self.stopbutton = tk.Button(controlframe,image=imstop,relief=tk.FLAT, borderwidth=0, command=self.cmd_stop, state=self.tkDisabled)
    self.ffwdbutton = tk.Button(controlframe,image=imffwd,relief=tk.FLAT, borderwidth=0, command=self.cmd_ffwd, state=self.tkDisabled)
    self.nextbutton = tk.Button(controlframe,image=imnext,relief=tk.FLAT, borderwidth=0, command=self.cmd_next, state=self.tkDisabled)
    filebutton = tk.Button(controlframe,image=imfile,relief=tk.FLAT, borderwidth=0, command=self.cmd_file)
    aboutbutton = tk.Button(controlframe,image=imabout,relief=tk.FLAT, borderwidth=0, command=self.cmd_about)
    self.backbutton.grid(row=0,column=0)
    self.rwndbutton.grid(row=0,column=1)
    self.playbutton.grid(row=0,column=2)
    self.stopbutton.grid(row=0,column=3)
    self.ffwdbutton.grid(row=0,column=4)
    self.nextbutton.grid(row=0,column=5)
    tk.Label(controlframe,text="").grid(row=0,column=6)
    volumeframe = tk.Frame(controlframe,padx=0)
    volumeframe.grid(row=0,column=7)
    imvup = PhotoImage(file=joinpath(self.path, 'images', 'player_vup.png'))
    imvdn = PhotoImage(file=joinpath(self.path, 'images', 'player_vdn.png'))
    self.vupbutton = tk.Button(volumeframe,image=imvup,relief=tk.FLAT, borderwidth=0, command=self.cmd_v_up, state=self.tkDisabled)
    self.vdnbutton = tk.Button(volumeframe,image=imvdn,relief=tk.FLAT, borderwidth=0, command=self.cmd_v_dn, state=self.tkDisabled)
    self.vupbutton.grid(row=0)
    self.vdnbutton.grid(row=1)
    tk.Label(controlframe,text="").grid(row=0,column=8)
    filebutton.grid(row=0,column=9)
    tk.Label(controlframe,text="").grid(row=0,column=10)
    aboutbutton.grid(row=0,column=11)
    self.ltracktime = tk.Label(self.root)
    self.ltracktime.grid(row=0, column=2, columnspan=5, sticky=tk.E)
    self.ltracktime.config(width=15,justify=tk.RIGHT,font=("Helvetica", 9, 'bold'))
    if self.showSlider:
      self.slider = tk.Scale(self.root, from_=0, to=100, orient=tk.HORIZONTAL, showvalue=0, sliderlength=12, command=self.slider_callback, borderwidth=1, relief=tk.GROOVE, sliderrelief=tk.RAISED, state=self.tkDisabled)
      self.slider.grid(row=1, columnspan=7, sticky=tk.W + tk.E)
      self.slider.bind('<Button-1>',self.slider_dn)
      self.slider.bind('<Button-3>',self.slider_dn3)
      self.slider.bind('<B1-Motion>',self.slider_mv)
      self.slider.bind('<ButtonRelease-1>',self.slider_up)
      self.sliderStatus = 0  # 0 = nothing; 1 = slider clicked, 2 = slider moving
    
    self.md_template = [ ]
    self.md_label = [ ]
    self.doMenu = False
    for i in range(0, 4):
      if config.has_option("metadata", "label"+str(i+1))==1:
        self.md_label.append(tk.Label(self.root))
        self.md_label[i].grid(row=i+2, columnspan=8, sticky=tk.W + tk.E)
        self.md_label[i].config(pady=0, padx=2, borderwidth=1, relief=tk.GROOVE, text="", font=("Helvetica", self.fontsize), anchor=tk.W, justify=tk.LEFT)
        thislabel = config.get("metadata", "label"+str(i+1))
        if thislabel.find('trackmenu') != -1:
            self.doMenu = True
            self.selectedMenuItem = tk.StringVar()
            self.md_label[i].bind('<Button-1>',self.showMenu)
            thislabel = thislabel.replace('trackmenu ','')
            thislabel = thislabel.replace(' trackmenu','')
            thislabel = thislabel.replace('trackmenu','')
        self.md_template.append(thislabel)
      else:
        break
      
    if self.showCover:
      self.albumart = tk.Label(self.root)
      self.albumart.grid(row=i+3, columnspan=8)
      if self.showBlankCover:
        imagedata = Image.open(joinpath(self.path, 'images', 'blank.jpg'))
        imagedata.thumbnail(self.coverMaxSize, Image.ANTIALIAS)
        tkalbumart = PhotoImage(imagedata)
        self.albumart.config(image=tkalbumart)
      else:
        self.albumart.grid_remove()

    self.root.bind("<KeyPress>", self.keypress)
    self.aboutimagepath = joinpath(self.path, 'images', 'about.jpg')

    if loadfile != '':
      self.load_file(loadfile)

    self.root.mainloop()
  
  def keypress(self, event):
    if event.keycode == self.key_back:
      if self.gotfile == 1:
        self.cmd_back()
    elif event.keycode == self.key_next:
      if self.gotfile == 1:
        self.cmd_next()
    elif event.keycode == self.key_rwnd:
      if self.gotfile == 1:
        self.cmd_rwnd()
    elif event.keycode == self.key_ffwd:
      if self.gotfile == 1:
        self.cmd_ffwd()
    elif event.keycode == self.key_play:
      if self.gotfile == 1:
        self.cmd_play()
    elif event.keycode == self.key_stop:
      if self.gotfile == 1:
        self.cmd_stop()
    elif event.keycode == self.key_file:
      self.cmd_file()
    elif event.keycode == self.key_about:
        self.cmd_about()
    elif event.keycode == self.key_v_up:
      if self.gotfile == 1:
        self.cmd_v_up()
    elif event.keycode == self.key_v_dn:
      if self.gotfile == 1:
        self.cmd_v_dn()

  def showMenu(self, event):
      if self.gotfile == 1:
        self.trackmenu.post( event.x_root, event.y_root )

  def changeTracks(self):
      if self.gotfile == 1:
          thistrackstring = unicode(self.selectedMenuItem.get())
          thistracknum = int(thistrackstring[0:thistrackstring.find('.')])
          self.stream.position = self.cue.tracks[thistracknum-1].index_samp
          self.update_track()
  
  def cmd_v_up(self):
    thisvol = self.stream.volume
    thisvol = thisvol * self.volStep
    if thisvol > 1: thisvol = 1
    self.stream.volume = thisvol

  def cmd_v_dn(self):
    thisvol = self.stream.volume
    thisvol = thisvol / self.volStep
    if thisvol < 0: thisvol = 0
    self.stream.volume = thisvol

  def slider_dn(self, event):
    # tkinter's scale widget calls the callback function whether the slider is changed programmatically, or by the user. 
    # This means that when AP51 updates the slider because of a change in audio position, the slider tries to update AP51 
    # (by repositioning the audio, as would be appropriate if the user had moved the slider), causing pain-in-the-ass skips 
    # in playback. This workaround keeps track of manual (user) slider updates, uh, manually, and screw the callback.
    if self.gotfile == 1:
      if self.slider.identify(event.x, event.y) == "slider":
        self.sliderStatus = 1
      elif self.slider.identify(event.x, event.y) == "trough1":
        self.cmd_rwnd()
      elif self.slider.identify(event.x, event.y) == "trough2":
        self.cmd_ffwd()
  
  def slider_dn3(self, event):
    self.sliderStatus = 0
    
  def slider_mv(self, event):
    if self.sliderStatus > 0:
      self.ltracktime.config(text=">"+self.cue.getTimeString_MS((self.slider.get()-self.cue.tracks[self.currenttrack-1].index_samp) / self.cue.ms2samp) + " / " + self.cue.tracks[self.currenttrack-1].sduration+"<")
      self.sliderStatus = 2
      
  def slider_up(self, event):
    if self.sliderStatus == 2:
      self.stream.position = self.slider.get()
    self.sliderStatus = 0
    
  def slider_callback(self,pos):
    pass
    
  def timer_callback(self):
    pos = self.stream.position
    if pos >= (self.cue.tracks[self.currenttrack-1].index_samp + self.cue.tracks[self.currenttrack-1].samples):
      if self.currenttrack < self.cue.numtracks:
        self.currenttrack = self.currenttrack + 1
      self.update_track()
    elif pos < self.cue.tracks[self.currenttrack-1].index_samp:
      if self.currenttrack > 1:
        self.currenttrack = self.currenttrack - 1
      self.update_track()
    if (self.showSlider) and (self.sliderStatus == 0):
      self.slider.set(pos)
    if self.stream.playing == 1:
      self.root.after(self.refreshms,self.timer_callback)
    elif self.ltracktime.cget("state")==self.tkActive:
      self.cmd_stop()
    self.ltracktime.config(text=self.cue.getTimeString_MS((pos-self.cue.tracks[self.currenttrack-1].index_samp) / self.cue.ms2samp) + " / " + self.cue.tracks[self.currenttrack-1].sduration)
    
  def update_track(self):
    for i in range(0, len(self.md_label)):
      thislabel = unicode(eval("\"" + self.md_template[i] + "\""))
      thislabel = thislabel.replace("albumname",self.cue.title)
      thislabel = thislabel.replace("albumyear",self.cue.year)
      thislabel = thislabel.replace("albumduration",self.cue.sduration)
      thislabel = thislabel.replace("albumnumtracks",unicode(self.cue.numtracks))
      thislabel = thislabel.replace("albumperformer",self.cue.performer)
      thislabel = thislabel.replace("tracknumber",unicode(self.currenttrack))
      thislabel = thislabel.replace("trackname",self.cue.tracks[self.currenttrack-1].name)
      thislabel = thislabel.replace("trackduration",self.cue.tracks[self.currenttrack-1].sduration)
      thislabel = thislabel.replace("trackperformer",self.cue.tracks[self.currenttrack-1].performer)
      for j in self.cue.remarks:
        thislabel = thislabel.replace("REM_"+j.key,j.val+"\nREM_"+j.key)
      for j in self.cue.remarks:
        thislabel = thislabel.replace("\nREM_"+j.key,'')
      while thislabel.find('REM_') >-1:
        j = thislabel.find('REM_')
        k = thislabel.find(' ',j)
        if k == -1:
          thislabel = thislabel.replace(thislabel[j:],'')
        else:
          thislabel = thislabel.replace(thislabel[j:k],'')
      thislabel = thislabel.replace("\n\n\n","\n\n")
      self.md_label[i].config(text=thislabel)

    thislabel = unicode(self.titleText.replace("albumname",self.cue.title))
    thislabel = thislabel.replace("albumyear",self.cue.year)
    thislabel = thislabel.replace("albumduration",self.cue.sduration)
    thislabel = thislabel.replace("albumnumtracks",unicode(self.cue.numtracks))
    thislabel = thislabel.replace("albumperformer",self.cue.performer)
    thislabel = thislabel.replace("tracknumber",unicode(self.currenttrack))
    thislabel = thislabel.replace("trackname",self.cue.tracks[self.currenttrack-1].name)
    thislabel = thislabel.replace("trackduration",self.cue.tracks[self.currenttrack-1].sduration)
    thislabel = thislabel.replace("trackperformer",self.cue.tracks[self.currenttrack-1].performer)
    for j in self.cue.remarks:
      thislabel = thislabel.replace("REM_"+j.key,j.val)
    self.root.title(thislabel)
    if self.showSlider:
      self.slider.config(from_=self.cue.tracks[self.currenttrack-1].index_samp, to=(self.cue.tracks[self.currenttrack-1].index_samp+self.cue.tracks[self.currenttrack-1].samples))
#    if self.gotfile & self.doMenu:
#      print self.currenttrack
#      self.selectedMenuItem = unicode(str(self.cue.tracks[self.currenttrack].number) + ". " + self.cue.tracks[self.currenttrack].name)

  def cmd_play(self):
    if self.stream.playing == 1:
      self.stream.playing = 0
      self.playbutton.config(image=self.implay)
      self.ltracktime.config(state=self.tkDisabled)
    else:
      self.stream.playing = 1
      self.playbutton.config(image=self.impause)
      self.ltracktime.config(state=self.tkActive)
      self.root.after(self.refreshms,self.timer_callback)

  def cmd_stop(self):
    self.stream.playing = 0
    self.playbutton.config(image=self.implay)
    self.stream.reset()
    self.currenttrack = 1
    self.ltracktime.config(state=self.tkDisabled)
    self.timer_callback()
    self.update_track()

  def cmd_back(self):
    if self.currenttrack > 1:
      if self.stream.position < self.cue.tracks[self.currenttrack-1].index_samp+self.skipbuffsamp:
        self.currenttrack = self.currenttrack - 1
    if self.doMenu:
      self.trackmenu.invoke(self.currenttrack-1)
    else:
      self.stream.position = self.cue.tracks[self.currenttrack-1].index_samp
      self.update_track()

  def cmd_next(self):
    if self.currenttrack < self.cue.numtracks:
      if self.stream.position > (self.cue.tracks[self.currenttrack-1].index_samp+self.cue.tracks[self.currenttrack-1].samples)-self.skipbuffsamp:
        self.currenttrack = self.currenttrack + 2
      else:
        self.currenttrack = self.currenttrack + 1
      if self.doMenu:
        self.trackmenu.invoke(self.currenttrack-1)
      else:
        self.stream.position = self.cue.tracks[self.currenttrack-1].index_samp
        self.update_track()

  def cmd_rwnd(self):
    pos = self.stream.position
    if pos - self.seeksamp > 0:
      self.stream.position = self.stream.position - self.seeksamp
    else:
      self.stream.position = 0
    self.timer_callback()

  def cmd_ffwd(self):
    pos = self.stream.position
    if pos + self.seeksamp < self.cue.samples:
      self.stream.position = self.stream.position + self.seeksamp
    else:
      self.stream.position = self.cue.samples
    self.timer_callback()
    
  def cmd_about(self):
    from appVersion import versionInfo
    ver = versionInfo()
    ver.showAbout(self.root, self.aboutimagepath, self.audiolib)
    
  def cmd_file(self):
    from tkFileDialog import askopenfilename
#    filename = askopenfilename(filetypes=(('FLAC Files & Cue Sheets', '*.flac *.cue'),('FLAC Files', '*.flac'),('Cue Sheets', '*.cue'),("All Files", "*")))
    filename = askopenfilename(title='Select FLAC file',filetypes=(('FLAC Files', '*.flac'),("All Files", "*")),initialdir=self.initialDir)
    if filename:
      self.load_file(filename)
      
  def load_file(self, filename):
    from os.path import splitext
    from os.path import dirname
    from os.path import basename
    from os.path import exists as pathexists
    from os.path import join as joinpath
    from ImageTk import PhotoImage
    from PIL import Image
    import tkMessageBox
    extension = splitext(filename)[1]
    basename = splitext(basename(filename))[0]
    filepath = dirname(filename)
    self.initialDir = filepath
    if extension == ".flac":
      from mutagen.flac import FLAC as md
      metadata = md(filename)
      thissamples = metadata.info.total_samples
      thissr = metadata.info.sample_rate
      try:
        thiscue = metadata[self.flactagforcue][0]
      except:
        thiscue = ''
      if thiscue != '':
        self.cue.getMetadataFromCue(thiscue,thissamples,thissr)
      else:
        if pathexists(joinpath(filepath,basename+".cue")):
          self.cue.getMetadataFromCue(self.readFile(joinpath(filepath,basename+".cue")),thissamples,thissr)
        elif pathexists(joinpath(filepath,basename+".flac.cue")):
          self.cue.getMetadataFromCue(self.readFile(joinpath(filepath,basename+".flac.cue")),thissamples,thissr)
        else:
          if metadata.cuesheet != None:
            self.cue.getMetadataFromMutagen(metadata)
          else:
            tkMessageBox.showinfo(self.name,"Cannot find a CUE sheet!\n\nIt should be either embedded in the flac file, or in the same folder, and with the same basename")
            return
    else:
      tkMessageBox.showinfo(self.name,"Please select FLAC files only!")
      return

    if self.showCover:
      gotpic = 0
      if len(metadata.pictures) > 0:
        import StringIO
        for pic in metadata.pictures:
          if pic.type == 3:
            self.imagedata = Image.open(StringIO.StringIO(pic.data))
            gotpic = 1
        if gotpic == 0:
          self.imagedata = Image.open(StringIO.StringIO(metadata.pictures[0]))
          gotpic = 1
      elif metadata.has_key('COVERART'):
        # TODO: UNTESTED!
        import base64, StringIO
        self.imagedata = Image.open(StringIO.StringIO(base64.b64decode(metadata["COVERART"])))
        gotpic = 1
      elif pathexists(joinpath(filepath,basename+".jpg")):
        self.imagedata = Image.open(joinpath(filepath,basename+".jpg"))
        gotpic = 1
      elif pathexists(joinpath(filepath,basename+".png")):
        self.imagedata = Image.open(joinpath(filepath,basename+".png"))
        gotpic = 1
      elif pathexists(joinpath(filepath,basename+".flac.jpg")):
        self.imagedata = Image.open(joinpath(filepath,basename+".flac.jpg"))
        gotpic = 1
      elif pathexists(joinpath(filepath,basename+".flac.png")):
        self.imagedata = Image.open(joinpath(filepath,basename+".flac.png"))
        gotpic = 1
      elif self.showBlankCover:
        self.imagedata = Image.open(joinpath(self.path, 'images', 'blank.jpg'))
        gotpic = 1
      if gotpic == 1:
        self.imagedata.thumbnail(self.coverMaxSize, Image.ANTIALIAS)
        self.tkalbumart = PhotoImage(self.imagedata)
        self.albumart.config(image=self.tkalbumart)
        self.albumart.grid()
      else:
        self.albumart.grid_remove()

    self.skipbuffsamp = self.skipbuffms * self.cue.ms2samp
    self.seeksamp = self.seekms * self.cue.ms2samp
    self.currenttrack = 1
    self.update_track()
    self.ltracktime.config(text="00:00 / 00:00")
    if self.gotfile == 1:
        thisvol = self.stream.volume
        self.stream.playing = 0
    else:
      thisvol = 1
      from Tkinter import NORMAL as tkNormal
      self.backbutton.config(state = tkNormal)
      self.rwndbutton.config(state = tkNormal)
      self.playbutton.config(state = tkNormal)
      self.stopbutton.config(state = tkNormal)
      self.ffwdbutton.config(state = tkNormal)
      self.nextbutton.config(state = tkNormal)
      self.vupbutton.config(state = tkNormal)
      self.vdnbutton.config(state = tkNormal)
      if self.showSlider:
        self.slider.config(state = tkNormal)
    self.stream = self.device.open_sound(filename, 1)
    self.stream.volume = thisvol

    if self.doMenu == True:
        from Tkinter import Menu
        self.trackmenu = Menu(self.root, tearoff=0)
        for track in self.cue.tracks:
            self.trackmenu.add_radiobutton( label = unicode(str(track.number) + ". " + track.name), variable = self.selectedMenuItem, command = self.changeTracks)
        self.trackmenu.invoke(0)
#        self.selectedMenuItem = unicode(str(self.cue.tracks[0].number) + ". " + self.cue.tracks[0].name)

    self.gotfile = 1
    self.cmd_play()
  
  def readFile(self,filename):
    try:
      import codecs
      fin = codecs.open(filename, "r", "utf8")
      contents = fin.read()
    finally:
      fin.close()
    return contents
  
  def raiseError(self,err):
    pass
  
ThisApp = AudioPlayer51()
